{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bqBiunVBNaRg"
      },
      "source": [
        "# 다중 에이전트 계층 구조에서 여러 에이전트가 협업하도록 하기\n",
        "_작성자: [Aymeric Roucher](https://huggingface.co/m-ric), 번역: [김하림](https://github.com/harheem)_\n",
        "\n",
        "> 이 튜토리얼은 고급 수준이므로, 시작하기 전에 [이 에이전트 쿡북](agents)에서 다루는 기본 개념을 알고가는 것이 좋습니다!\n",
        "\n",
        "우리는 이 노트북에서 **다중 에이전트 웹 브라우저를 만들 것입니다. 여러 에이전트가 웹을 사용하여 문제를 해결하기 위해 협업하는 에이전트 시스템입니다!**\n",
        "\n",
        "이 시스템은 간단한 계층 구조로 되어있습니다. 여기서 `ManagedAgent` 객체를 사용하여 웹 검색 에이전트를 관리합니다. 이 구조를 통해 웹 검색 에이전트의 기능을 효과적으로 제어하고 조정할 수 있습니다.\n",
        "\n",
        "```\n",
        "              +-----------------+\n",
        "              |   관리자 에이전트   |\n",
        "              +-----------------+\n",
        "                       |\n",
        "        _______________|______________\n",
        "       |                              |\n",
        "  코드 인터프리터        +--------------------------------+\n",
        "      도구            |         관리되는 에이전트           |\n",
        "                     |      +------------------+      |\n",
        "                     |      |   웹 검색 에이전트   |      |\n",
        "                     |      +------------------+      |\n",
        "                     |         |            |         |\n",
        "                     |    웹 검색 도구         |         |\n",
        "                     |               웹페이지 방문 도구    |\n",
        "                     +--------------------------------+                     \n",
        "\n",
        "```\n",
        "\n",
        "환경 구성부터 시작해보겠습니다.\n",
        "\n",
        "다음 명령어를 실행하여 필요한 패키지를 설치하세요."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "CYWYKDSVNaRi"
      },
      "outputs": [],
      "source": [
        "!pip install markdownify duckduckgo-search \"transformers[agents]\" --upgrade -q"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Hugging Face Hub API를 사용하기 위해서는 로그인이 필요합니다.\n",
        "\n",
        "아래 코드를 실행하여 로그인해주세요."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "from huggingface_hub import notebook_login\n",
        "\n",
        "notebook_login()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "⚡️ 우리의 에이전트는 [Qwen/Qwen2.5-72B-Instruct](https://huggingface.co/Qwen/Qwen2.5-72B-Instruct) 모델을 사용합니다. 이 모델은 `HfApiEngine` 클래스를 통해 Hugging Face의 Inference API로 호출됩니다. Inference API를 활용하면 다양한 오픈 소스 모델을 빠르고 쉽게 실행할 수 있습니다.\n",
        "\n",
        "_Note:_ Inference API는 다양한 기준에 따라 모델을 호스팅하며, 배포된 모델은 사전 통지 없이 업데이트되거나 교체될 수 있으므로 [여기](https://huggingface.co/docs/api-inference/supported-models)에서 자세한 내용을 확인해보세요.\n",
        "\n",
        "_역주:_ 이 노트북을 실행하려면 Hugging Face에서 발급받은 HF_TOKEN을 Google Colab의 보안 변수(Secrets)로 등록해야 합니다. 또한, 여기서 사용되는 모델들은 Hugging Face의 Pro 구독이 필요합니다. 무료 계정으로는 접근이 제한될 수 있으니 주의해 주세요."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "04PbAdHBNaRi"
      },
      "outputs": [],
      "source": [
        "model = \"Qwen/Qwen2.5-72B-Instruct\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "owjHzaaLNaRi"
      },
      "source": [
        "### 🔍 웹 검색 도구 만들기\n",
        "\n",
        "웹 브라우징을 위해 우리는 기존에 있는 [`DuckDuckGoSearchTool`](https://github.com/huggingface/transformers/blob/main/src/transformers/agents/search.py) 도구를 사용할 것입니다. 이 도구는 Google 검색과 비슷한 기능을 제공합니다.\n",
        "\n",
        "그러나 `DuckDuckGoSearchTool`이 찾은 웹페이지의 내용을 자세히 볼 수 있는 기능도 필요합니다.\n",
        "이를 위해 라이브러리에 있는 `VisitWebpageTool`을 사용할 수도 있지만, 우리는 이 도구를 직접 만들어보며 그 과정을 이해해 보려고 합니다.\n",
        "\n",
        "그래서 `markdownify`를 사용하여 `VisitWebpageTool` 도구를 처음부터 만들어 보도록 하겠습니다."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "id": "Ye74sBu3NaRj"
      },
      "outputs": [],
      "source": [
        "import re\n",
        "import requests\n",
        "from markdownify import markdownify as md\n",
        "from requests.exceptions import RequestException\n",
        "from transformers.agents import tool\n",
        "from urllib.parse import unquote\n",
        "\n",
        "\n",
        "@tool\n",
        "def visit_webpage(url: str) -> str:\n",
        "    \"\"\"주어진 URL 웹페이지를 방문하고 그 내용을 마크다운 문자열로 반환합니다.\n",
        "\n",
        "    Args:\n",
        "        url: 방문할 웹페이지의 URL\n",
        "\n",
        "    Returns:\n",
        "        마크다운으로 변환된 웹페이지 내용, 또는 요청 실패 시 오류 메시지\n",
        "    \"\"\"\n",
        "    try:\n",
        "        # URL로 GET 요청 보내기\n",
        "        response = requests.get(url)\n",
        "        response.raise_for_status()  # 잘못된 상태 코드에 대한 예외 처리\n",
        "\n",
        "        # HTML 내용을 마크다운으로 변환하기\n",
        "        markdown_content = md(response.text).strip()\n",
        "\n",
        "        # 중복된 개행 문자 제거하기\n",
        "        markdown_content = re.sub(r\"\\n{3,}\", \"\\n\\n\", markdown_content)\n",
        "\n",
        "        # URL 디코딩하기\n",
        "        markdown_content = re.sub(r'\\((.*?)\\)', lambda m: '(' + unquote(m.group(1)) + ')', markdown_content)\n",
        "\n",
        "        return markdown_content\n",
        "\n",
        "    except RequestException as e:\n",
        "        return f\"웹페이지 가져오기 오류: {str(e)}\"\n",
        "    except Exception as e:\n",
        "        return f\"예상치 못한 오류 발생: {str(e)}\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jD_kJGxCNaRj"
      },
      "source": [
        "이제, 우리의 도구를 테스트해봅시다!\n",
        "\n",
        "\n",
        "_역주:_ 한글이 포함된 URL의 디코딩을 처리하기 위해 코드를 추가하였습니다."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "q45tiLuGNaRj",
        "outputId": "cf20dfb9-41d9-4c35-ab3a-5aaba8e4077f"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "허깅 페이스 \\- 위키백과, 우리 모두의 백과사전\n",
            "\n",
            "[본문으로 이동](#bodyContent)\n",
            "\n",
            "주 메뉴\n",
            "\n",
            "주 메뉴\n",
            "사이드바로 이동\n",
            "숨기기\n",
            "\n",
            " 둘러보기\n",
            " \n",
            "\n",
            "* [대문](/wiki/위키백과:대문 \"대문으로 가기 [z]\")\n",
            "* [최근 바뀜](/wiki/특수:최근바뀜 \"위키의 최근 바뀐 목록 [r]\")\n",
            "* [요즘 화제](/wiki/포털:요즘_화제 \"최근의 소식 알아 보기\")\n",
            "* [임의의 문서로](/wiki/특수:임의문서 \"무작위로 선택된 문서 불러오기 [x]\")\n",
            "\n",
            " 사용자 모임\n",
            " \n",
            "\n",
            "* [사랑방](/wiki/위키백과:사랑방)\n",
            "* [사용자 모임](/wiki/위키백과:사용자_모임 \"위키백과 참여자를 위한 토론/대화 공간입니다.\")\n",
            "* [관리 요청](/wiki/위키백과:요청)\n",
            "\n",
            " 편집 안내\n",
            " \n",
            "\n",
            "* [소개](/wiki/도움말:소개)\n",
            "* [도움말](/wiki/위키백과:도움말 \"도움말\")\n",
            "* [정책과 지침](/wiki/위키백과:정책과_지침)\n",
            "* [질문방](/wiki/위키백과:질문방)\n",
            "\n",
            "[![](\n"
          ]
        }
      ],
      "source": [
        "print(visit_webpage(\"https://ko.wikipedia.org/wiki/Hugging_Face\")[:500])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8RI2SoklNaRj"
      },
      "source": [
        "## 다중 에이전트 시스템 구축하기 🤖🤝🤖\n",
        "\n",
        "이제 `search`와 `visit_webpage` 도구를 모두 갖추었으니, 이를 이용해 웹 에이전트를 만들 수 있습니다.\n",
        "\n",
        "이 에이전트를 어떻게 구성하는 것이 좋을까요?\n",
        "- 웹 브라우징은 병렬 도구 호출이 필요 없는 단일 타임라인 작업이므로, JSON 도구 호출이 적합합니다. 따라서 `ReactJsonAgent`를 선택합니다.\n",
        "- 또한, 웹 검색은 때때로 정확한 답변을 찾기 위해 여러 페이지를 탐색해야 할 수 있으므로, `max_iterations`를 10으로 늘리는 것이 좋습니다."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "id": "iWz8z2a-NaRk"
      },
      "outputs": [],
      "source": [
        "from transformers.agents import (\n",
        "    ReactCodeAgent,\n",
        "    ReactJsonAgent,\n",
        "    HfApiEngine,\n",
        "    ManagedAgent,\n",
        ")\n",
        "from transformers.agents.search import DuckDuckGoSearchTool\n",
        "\n",
        "llm_engine = HfApiEngine(model)\n",
        "\n",
        "web_agent = ReactJsonAgent(\n",
        "    tools=[DuckDuckGoSearchTool(), visit_webpage],\n",
        "    llm_engine=llm_engine,\n",
        "    max_iterations=10,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "o9SSuIIwNaRk"
      },
      "source": [
        "그런 다음 이 웹 검색 에이전트를 `ManagedAgent`로 감싸줍니다. 이렇게 하면 상위의 관리자 에이전트가 이 에이전트를 쉽게 제어할 수 있습니다."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "id": "dbNDCILRNaRk"
      },
      "outputs": [],
      "source": [
        "managed_web_agent = ManagedAgent(\n",
        "    agent=web_agent,\n",
        "    name=\"search\",\n",
        "    description=\"Runs web searches for you. Give it your query as an argument.\",\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Aj06e4Q1NaRk"
      },
      "source": [
        "이제 관리자 에이전트를 생성합니다. 이때 `managed_agents` 매개변수에 우리가 만든 관리 받는 에이전트를 전달합니다.\n",
        "\n",
        "관리자 에이전트는 전체적인 계획 수립과 복잡한 사고를 담당해야 하므로, 고급 추론 능력이 필요합니다. 이런 이유로 `ReactCodeAgent`를 사용하는 것이 가장 적합할 것 같습니다.\n",
        "\n",
        "마지막으로, 현재 연도와 관련된 질문을 처리하기 위해 `additional_authorized_imports=[\"time\", \"datetime\"]`을 설정에 추가합니다. 이렇게 하면 에이전트가 시간과 관련 정보를 다룰 수 있게 됩니다."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "id": "zJHVCwWRNaRk"
      },
      "outputs": [],
      "source": [
        "manager_agent = ReactCodeAgent(\n",
        "    tools=[],\n",
        "    llm_engine=llm_engine,\n",
        "    managed_agents=[managed_web_agent],\n",
        "    additional_authorized_imports=[\"time\", \"datetime\"],\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zTTIQqP-NaRk"
      },
      "source": [
        "이것으로 모든 준비가 끝났습니다! 이제 우리의 시스템을 실행해봅시다.\n",
        "계산이 필요한 질문을 던져보겠습니다."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "wiQv7ZetNaRk",
        "outputId": "5e81551a-51f6-464d-db1d-ca3664be6d60"
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "\u001b[32;20;1m======== New task ========\u001b[0m\n",
            "\u001b[37;1mStripe는 몇 년 전에 설립되었나요?\u001b[0m\n",
            "\u001b[33;1m=== Agent thoughts:\u001b[0m\n",
            "\u001b[0mThought: 먼저 Stripe 회사가 언제 설립되었는지 알아봐야 합니다. 이를 위해 `search` 팀 멤버에게 요청을 보낼 것입니다.\u001b[0m\n",
            "\u001b[33;1m>>> Agent is executing the code below:\u001b[0m\n",
            "\u001b[0m\u001b[38;5;7mrequest\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;144m\"\u001b[39m\u001b[38;5;144mWhen was Stripe company founded?\u001b[39m\u001b[38;5;144m\"\u001b[39m\n",
            "\u001b[38;5;109mprint\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7msearch\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7mrequest\u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;7mrequest\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[0m\n",
            "\u001b[33;1m====\u001b[0m\n",
            "\u001b[32;20;1m======== New task ========\u001b[0m\n",
            "\u001b[37;1mYou're a helpful agent named 'search'.\n",
            "You have been submitted this task by your manager.\n",
            "---\n",
            "Task:\n",
            "When was Stripe company founded?\n",
            "---\n",
            "You're helping your manager solve a wider task: so make sure to not provide a one-line answer, but give as much information as possible so that they have a clear understanding of the answer.\n",
            "\n",
            "Your final_answer WILL HAVE to contain these parts:\n",
            "### 1. Task outcome (short version):\n",
            "### 2. Task outcome (extremely detailed version):\n",
            "### 3. Additional context (if relevant):\n",
            "\n",
            "Put all these in your final_answer tool, everything that you do not pass as an argument to final_answer will be lost.\n",
            "And even if your task resolution is not successful, please return as much context as possible, so that your manager can act upon this feedback.\u001b[0m\n",
            "\u001b[33;1m=== Agent thoughts:\u001b[0m\n",
            "\u001b[0mThought: To answer this question, I need to search for information about Stripe's founding. I will use the web_search tool to find the relevant information.\u001b[0m\n",
            "\u001b[33;1m>>> Calling tool: 'web_search' with arguments: {'query': 'When was Stripe company founded?'}\u001b[0m\n",
            "\u001b[33;1m=== Agent thoughts:\u001b[0m\n",
            "\u001b[0mThought: From the results, it's clear that Stripe was founded in 2010 by Patrick and John Collison. I will gather more details from these sources to provide a comprehensive answer.\u001b[0m\n",
            "\u001b[33;1m>>> Calling tool: 'visit_webpage' with arguments: {'url': 'https://en.wikipedia.org/wiki/Stripe,_Inc.'}\u001b[0m\n",
            "\u001b[33;1m=== Agent thoughts:\u001b[0m\n",
            "\u001b[0mThought: The Wikipedia page provides a detailed overview of Stripe, including its founding year and various milestones. I have all the information needed to provide an extensive answer. Now I will use this information to construct a detailed final answer.\u001b[0m\n",
            "\u001b[33;1m>>> Calling tool: 'final_answer' with arguments: {'answer': \"### 1. Task outcome (short version):\\nStripe, Inc. was founded in 2010 by Irish brothers Patrick and John Collison.\\n\\n### 2. Task outcome (extremely detailed version):\\nStripe, Inc. is an Irish-American multinational financial services and software as a service (SaaS) company. It was founded in 2010 by brothers Patrick and John Collison. The company is dual-headquartered in South San Francisco, California, United States, and Dublin, Ireland.\\n\\nThe founding of Stripe was driven by the Collison brothers' vision to provide a more accessible and user-friendly payment processing solution for online businesses. They started the company at a time when the e-commerce industry was rapidly growing, and there was a significant need for reliable and efficient payment processing services. The company officially launched in September 2011 after an extensive private beta.\\n\\nSince its founding, Stripe has experienced substantial growth and has expanded its services to multiple countries. It has also received significant investments from notable venture capitalists and tech entrepreneurs, including Peter Thiel, Elon Musk, Sequoia Capital, and Andreessen Horowitz. By 2023, Stripe had processed over $1 trillion in total payment volume and had a valuation of around $50 billion.\\n\\n### 3. Additional context (if relevant):\\n- **Key Milestones**:\\n  - **2010**: Founded by Patrick and John Collison.\\n  - **2011**: Officially launched in September after a private beta.\\n  - **2012**: Introduced Stripe Connect, a multiparty payments solution.\\n  - **2016**: Launched the Atlas platform to help startups register as U.S. corporations, targeting foreign entrepreneurs.\\n  - **2018**: Expanded to 25 countries and introduced Stripe Issuing, allowing businesses to create their own physical and digital cards.\\n  - **2021**: Raised $600 million, reaching a valuation of $95 billion.\\n  - **2023**: Completed a Series I fundraise of more than $6.5 billion at a $50 billion valuation.\\n\\n- **Services**: Stripe offers a wide range of financial services, including payment processing, billing, fraud prevention, point-of-sale solutions, and more.\\n\\n- **Partnerships and Acquisitions**: Stripe has formed strategic partnerships with major companies like Ford, Spotify, and Twitter. It has also made several acquisitions, such as Paystack and TaxJar, to expand its capabilities and footprint.\\n\\n- **Impact**: Stripe has played a significant role in shaping the e-commerce and fintech industries, providing tools and services that have enabled businesses of all sizes to process payments more efficiently and securely.\"}\u001b[0m\n",
            "\u001b[32;20;1m======== New task ========\u001b[0m\n",
            "\u001b[37;1mYou're a helpful agent named 'search'.\n",
            "You have been submitted this task by your manager.\n",
            "---\n",
            "Task:\n",
            "When was Stripe company founded?\n",
            "---\n",
            "You're helping your manager solve a wider task: so make sure to not provide a one-line answer, but give as much information as possible so that they have a clear understanding of the answer.\n",
            "\n",
            "Your final_answer WILL HAVE to contain these parts:\n",
            "### 1. Task outcome (short version):\n",
            "### 2. Task outcome (extremely detailed version):\n",
            "### 3. Additional context (if relevant):\n",
            "\n",
            "Put all these in your final_answer tool, everything that you do not pass as an argument to final_answer will be lost.\n",
            "And even if your task resolution is not successful, please return as much context as possible, so that your manager can act upon this feedback.\u001b[0m\n",
            "\u001b[33;1m=== Agent thoughts:\u001b[0m\n",
            "\u001b[0mThought: To answer this question, I need to search for information about Stripe's founding. I will use the web_search tool to find the relevant information.\u001b[0m\n",
            "\u001b[33;1m>>> Calling tool: 'web_search' with arguments: {'query': 'When was Stripe company founded?'}\u001b[0m\n",
            "\u001b[33;1m=== Agent thoughts:\u001b[0m\n",
            "\u001b[0mThought: The web_search results provide the information I need to answer the task. I will now craft a detailed final_answer to provide my manager with all relevant information.\u001b[0m\n",
            "\u001b[33;1m>>> Calling tool: 'final_answer' with arguments: {'answer': '### 1. Task outcome (short version):\\nStripe was founded in 2010.\\n\\n### 2. Task outcome (extremely detailed version):\\nStripe, Inc. is a technology company that provides software and APIs enabling businesses to accept online and mobile payments. Stripe was founded in 2010 by Irish brothers John Collison and Patrick Collison in Palo Alto, California. The company operates globally, offering services to businesses of all sizes, from startups to large enterprises.\\n\\n### 3. Additional context (if relevant):\\n- **Founders**: The company was founded by John Collison and Patrick Collison, who still serve as the president and CEO, respectively.\\n- **Early Investment**: In 2011, Stripe received a $2 million investment from notable investors, including Elon Musk, Peter Thiel, and Max Levchin.\\n- **Growth**: Since its founding, Stripe has grown significantly, becoming one of the largest payment processors in the world. As of 2020, the company was valued at over $70 billion.\\n- **Products**: Stripe has launched various products over the years, including Atlas, which aims to help entrepreneurs start and grow their businesses globally.'}\u001b[0m\n",
            "\u001b[33;1mPrint outputs:\u001b[0m\n",
            "\u001b[32;20m### 1. Task outcome (short version):\n",
            "Stripe was founded in 2010.\n",
            "\n",
            "### 2. Task outcome (extremely detailed version):\n",
            "Stripe, Inc. is a technology company that provides software and APIs enabling businesses to accept online and mobile payments. Stripe was founded in 2010 by Irish brothers John Collison and Patrick Collison in Palo Alto, California. The company operates globally, offering services to businesses of all sizes, from startups to large enterprises.\n",
            "\n",
            "### 3. Additional context (if relevant):\n",
            "- **Founders**: The company was founded by John Collison and Patrick Collison, who still serve as the president and CEO, respectively.\n",
            "- **Early Investment**: In 2011, Stripe received a $2 million investment from notable investors, including Elon Musk, Peter Thiel, and Max Levchin.\n",
            "- **Growth**: Since its founding, Stripe has grown significantly, becoming one of the largest payment processors in the world. As of 2020, the company was valued at over $70 billion.\n",
            "- **Products**: Stripe has launched various products over the years, including Atlas, which aims to help entrepreneurs start and grow their businesses globally.\n",
            "\u001b[0m\n",
            "\u001b[33;1m=== Agent thoughts:\u001b[0m\n",
            "\u001b[0mThought: 이제 Stripe가 2010년에 설립되었다는 것을 알았습니다. 현재 연도를 가져와서 Stripe의 나이를 계산해야 합니다.\u001b[0m\n",
            "\u001b[33;1m>>> Agent is executing the code below:\u001b[0m\n",
            "\u001b[0m\u001b[38;5;109;01mimport\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;109mdatetime\u001b[39m\n",
            "\n",
            "\u001b[38;5;7mstripe_founded_year\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;139m2010\u001b[39m\n",
            "\u001b[38;5;7mcurrent_year\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;7mdatetime\u001b[39m\u001b[38;5;109;01m.\u001b[39;00m\u001b[38;5;7mdatetime\u001b[39m\u001b[38;5;109;01m.\u001b[39;00m\u001b[38;5;7mnow\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[38;5;109;01m.\u001b[39;00m\u001b[38;5;7myear\u001b[39m\n",
            "\u001b[38;5;7mstripe_age_years\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;7mcurrent_year\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01m-\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;7mstripe_founded_year\u001b[39m\n",
            "\u001b[38;5;109mprint\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;144m\"\u001b[39m\u001b[38;5;144mStripe age (years):\u001b[39m\u001b[38;5;144m\"\u001b[39m\u001b[38;5;7m,\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;7mstripe_age_years\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[0m\n",
            "\u001b[33;1m====\u001b[0m\n",
            "\u001b[33;1mPrint outputs:\u001b[0m\n",
            "\u001b[32;20mStripe age (years): 14\n",
            "\u001b[0m\n",
            "\u001b[33;1m=== Agent thoughts:\u001b[0m\n",
            "\u001b[0mThought: 이제 Stripe가 14년 전에 설립되었다는 것을 확인했습니다. 이제 최종 답변을 반환하겠습니다.\u001b[0m\n",
            "\u001b[33;1m>>> Agent is executing the code below:\u001b[0m\n",
            "\u001b[0m\u001b[38;5;7mfinal_answer\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7mstripe_age_years\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[0m\n",
            "\u001b[33;1m====\u001b[0m\n",
            "\u001b[33;1mPrint outputs:\u001b[0m\n",
            "\u001b[32;20m\u001b[0m\n",
            "\u001b[33;1mLast output from code snippet:\u001b[0m\n",
            "\u001b[32;20m14\u001b[0m\n",
            "\u001b[32;20;1mFinal answer:\u001b[0m\n",
            "\u001b[32;20m14\u001b[0m\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "14"
            ]
          },
          "execution_count": 15,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "manager_agent.run(\"Stripe는 몇 년 전에 설립되었나요?\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qwnHiiibNaRk"
      },
      "source": [
        "이렇게 에이전트들이 협력하여 과제를 해결했습니다! ✅\n",
        "\n",
        "💡 이 시스템은 쉽게 더 많은 에이전트로 확장될 수 있습니다. 예를 들어, 한 에이전트는 코드 실행을 담당하고, 다른 에이전트는 웹 검색을, 또 다른 에이전트는 파일 로딩을 처리하는 식으로 말이죠.\n",
        "\n",
        "🤔💭 더 나아가 복잡한 트리 구조의 계층을 생각해볼 수도 있습니다. 최고 경영자(CEO) 에이전트가 여러 중간 관리자를 관리하고, 각 중간 관리자는 다시 여러 부하 직원을 관리하는 구조를 만들 수 있죠.\n",
        "\n",
        "심지어 더 많은 중간 관리 계층을 추가하고, 매일 여러 번의 회의를 하고, 스크럼 마스터와 함께 애자일 방식을 도입할 수도 있습니다. 그리고 각 새로운 구성 요소는 충분한 마찰을 추가하여 결국 아무 일도 완수되지 않도록 할 수 있겠죠... 음, 잠깐만요. 그건 아니겠네요. 우리의 단순한 구조를 유지하는 것이 좋겠습니다."
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "cookbook2",
      "language": "python",
      "name": "cookbook2"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.12.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
